#!/usr/bin/env python
# coding: utf-8

import openpyxl
import cv2
import numpy as np
import matplotlib.pyplot as plt
from math import sqrt
from xml.dom.minidom import parse
import pytesseract
import time
import os
print("温馨提示：本机为",os.cpu_count(),"核CPU")  
pytesseract.pytesseract.tesseract_cmd = r'C:\\Program Files\\Tesseract-OCR\\tesseract.exe'
tessdata_dir_config = '--tessdata-dir "c:\\Program Files\\Tesseract-OCR\\tessdata" --psm 7'


# 原始图像存放路径
# H:\20201111_dqform\test\0005
origin_img_path =  "H:\\20201111_dqform\\test\\test\\0001\\0001.jpg"
# img = cv2.imread(origin_img_path)
# 原始图像校正后的存放路径
jiaozheng_img_path = "H:\\20201111_dqform\\test\\test\\0001\\0001_jiaozheng.png"
# 纸质版表格文件的电子版路径
xml_read_path = "H:\\20201111_dqform\\test\\test\\0001\\0001.xml"
# 原始图像单元格存放地址
origin_cell_path = "H:\\20201111_dqform\\test\\test\\0001\\0001\\origin_cell\\"
# 单元格预处理后的图像的存放位置
binary_cell_path = "H:\\20201111_dqform\\test\\test\\0001\\0001\\binary_cell\\"
# 原始表格的读取路径
worksheet_read_path = "H:\\20201111_dqform\\test\\0001\\0001.xlsx"
# 识别结果电子表格的存放路径
worksheet_write_path = "H:\\20201111_dqform\\test\\0001\\0001_output.xlsx"



# 利用四个顶点的横纵坐标存在极值的关系

def contour_points(img):
   
    img_gray = cv2.cvtColor(img, cv2.COLOR_RGB2GRAY)
    img_gray = cv2.dilate(img_gray,None)
    # 焦点检测必须是float32
    img_gray = np.float32(img_gray)
    # 角点检测
    dst = cv2.cornerHarris(img_gray,2,3,0.04)
    # dst = cv2.dilate(dst, (7, 7))
    # 角点检测可视化检验
#     img_jiaodian = img
#     img_jiaodian[dst>0.001*dst.max()]=[0,0,255]
#     cv2.imwrite("C:\\Users\\lg\\Desktop\\form_ocr_excel\\hand write\\numbers_jiaodian.jpg", img_jiaodian)
    # np.where 返回一个元组，其中两个列表，分别为横纵坐标
    xy_points = np.where(dst > 0.0001* dst.max())
    # print(dst > 0.001 * dst.max())
    # print(xy_points)
    # 筛选轮廓四个角点
    # 其中x : row   y :col
    l_ru = 50

    l_lu = 200
    
    l_rd = 200

    l_ld = 200
  
    x_min = min (xy_points[0])
    x_max = max (xy_points[0])
    y_min = min (xy_points[1])
    y_max = max (xy_points[1])
    # print(x_min, x_max, y_min, y_max)
    
    for i in range(len(xy_points[0])):
    # print(contours[0][i][0][0],contours[0][i][0][1])
        x = xy_points[0][i] - x_min
        y = xy_points[1][i] - y_min
        l1 = sqrt(x**2 + y**2)
        if(l1 < l_ru):
#             x_ru_m = x
#             y_ru_m = y
            l_ru = l1
            x_left_up = xy_points[0][i]
            y_left_up = xy_points[1][i]
    
        x =  x_max - xy_points[0][i]
        y = xy_points[1][i] - y_min
        l2 = sqrt(x**2 + y**2)
        if(l2 < l_lu):
            l_lu = l2
            x_left_d = xy_points[0][i]
            y_left_d = xy_points[1][i]
        
        x = xy_points[0][i] - x_min
        y = y_max - xy_points[1][i]
        l3 = sqrt(x**2 + y**2)
        if(l3 < l_ld):
            l_ld = l3
            x_right_up = xy_points[0][i]
            y_right_up = xy_points[1][i]
        
        x = x_max - xy_points[0][i]
        y = y_max - xy_points[1][i] 
        l4 = sqrt(x**2 + y**2)
        if(l4 < l_rd):
            l_rd = l4
            x_right_down = xy_points[0][i]
            y_right_down = xy_points[1][i]
            # print(x_right_d)
            
    return([[x_left_up, y_left_up], [x_right_up, y_right_up], [x_left_d, y_left_d], [ x_right_down , y_right_down]])



# 校正图像
# 利用均值来对图像进行校正
def img_crroect(jiaozheng_img_path, contours_points,img):
    # pts1 = np.float32( [[x_right_up, y_right_up],[x_left_d, y_left_d],[x_right_d, y_right_d]])                  1                                2                          3
 
    # pts2 = np.float32([[x_left_up, y_right_up],[x_left_d, y_left_up],[x_left_d, y_right_up]])
    rows, cols, ch = img.shape
    x1 = int((contours_points[0][0] + contours_points[1][0]) / 2)
    y1 = int((contours_points[1][1] + contours_points[3][1]) / 2)

    x2 = int((contours_points[2][0] + contours_points[3][0]) / 2)
    y2 = int((contours_points[0][1] + contours_points[2][1]) / 2)

#     pts1 = np.float32([contours_points[1], contours_points[2],contours_points[3]])
#     pts2 = np.float32([ [x1, y1], [x2, y2], [x2, y1]])

# 这里注意一下：透射变换的坐标要求是w,h格式，而contour_points里面点的坐标格式是h, w
    pts1 = np.float32([[contours_points[0][1],contours_points[0][0]],[contours_points[1][1],contours_points[1][0]], 
                       [contours_points[2][1],contours_points[2][0]],[contours_points[3][1],contours_points[3][0]]])
    
    # 利用框线的四个角点均值对框线进行校正
    # 左上角点
    w1 = int((contours_points[0][1] + contours_points[2][1]) / 2)
    h1 = int((contours_points[0][0] + contours_points[1][0]) / 2)
    
    # 右上角点
    w2 = int((contours_points[1][1] + contours_points[3][1]) / 2)
    h2 = h1
    
    # 左下角点
    w3 = w1
    h3 = int((contours_points[2][0] + contours_points[3][0]) / 2)
    
    # 右下角点
    w4 = w2
    h4 = h3
    
    
    pts2 = np.float32([[contours_points[0][1],contours_points[0][0]],[contours_points[1][1], contours_points[0][1]], 
                       [contours_points[0][1], contours_points[2][0]], [contours_points[1][1], contours_points[2][0]]])

    # 利用四个角点的均值作为透射变换求解变换矩阵的值
    pts2 = np.float32([[w1,h1],[w2, h2], 
                       [w3, h3], [w4, h4]])
    
    
    # 获得放射矩阵
#     M = cv2.getAffineTransform(pts2, pts1)
#     # 利用仿射矩阵对图像进行旋转
#     dst = cv2.warpAffine(img, M, (cols, rows))
    M = cv2.getPerspectiveTransform(pts1,pts2)
    dst = cv2.warpPerspective(img,M,(cols, rows))
    # 对旋转之后的图像进行简单的剪裁，除去一些无谓的计算
    dst = dst[h1-5 : h3+5, w1-5 : w2+5, :]
    # plt.imshow(dst)
    if(cv2.imwrite(jiaozheng_img_path, dst)):
        print("图像校正成功，并成功保存！")
    else:
        print("图像校正失败！！！")
    return dst



# 原始图像存放路径
origin_img_path =  "H:\\20201111_dqform\\test\\0001\\0001.jpg"
# img = cv2.imread(origin_img_path)
# 原始图像校正后的存放路径
jiaozheng_img_path = "H:\\20201111_dqform\\test\\0001\\0001_jiaozheng.png"


# In[74]:


# 读取纸质版表格的原始图像
img = cv2.imread(origin_img_path)
# 获取表格框线的四个角的顶点
contours_points = contour_points(img)
# 对原始图像进行校正并保存
img_jiaozheng = img_crroect(jiaozheng_img_path, contours_points, img)


plt.imshow(img_jiaozheng)



def xml_read(xml_read_path):
    # XML文件的读取
    dom = parse(xml_read_path)
    # 获取文档元素对象
    data = dom.documentElement
    # 读取sheet
    sheet = data.getElementsByTagName('Worksheet')
    # 读取 table
    table = sheet[0].getElementsByTagName('Table')
    # 读取table中的默认参数
    # 默认行高 
    de_height = float(table[0].getAttribute("ss:DefaultRowHeight"))
    # 默认列宽
    de_width = float(table[0].getAttribute("ss:DefaultColumnWidth"))
    # 默认行数
    row_num = int(table[0].getAttribute("ss:ExpandedRowCount"))
    #默认列数
    col_num = int(table[0].getAttribute("ss:ExpandedColumnCount"))
    # 读取列宽
    # Column = table[0].getElementsByTagName('Column')
    # 读取列宽
    # 首先读取所有的列宽元素
    Column = table[0].getElementsByTagName('Column')
    col_list = col_num * [de_width]
    # 列宽元素的索引
    i = 0
    for col in Column:
        if(col.getAttribute("ss:Span") != '' and col.getAttribute("ss:Index") != ''):
            index = int(col.getAttribute("ss:Index"))
            span = int(col.getAttribute("ss:Span"))
            width = float(col.getAttribute("ss:Width"))
            col_list[index-1:index+span] = [width] * (span + 1)
            i = index + span 
        elif(col.getAttribute("ss:Span") == '' and col.getAttribute("ss:Index") != ''):
            index = int(col.getAttribute("ss:Index"))
            width = float(col.getAttribute("ss:Width"))
            col_list[index-1] = width
            i = index 
        elif(col.getAttribute("ss:Span") == '' and col.getAttribute("ss:Index") == ''):
            width = float(col.getAttribute("ss:Width"))
            col_list[i] = width
            i = i+1
            #print(width, i)
    
    # 读取所有的行高信息
    Rows = table[0].getElementsByTagName('Row')
        # 读取每一行行高
    height_list = []
    for row in Rows:
        # height_list.append(float(row.getAttribute("ss:Height")))
        if (row.getAttribute("ss:Height") == ''):
            height_list.append(float(de_height))
        else:
            height_list.append(float(row.getAttribute("ss:Height")))
    
   # 以左上顶点为原点，各个单元的位置关系,向下、向右为正方向
    All_cell_points = []
    # 坐标的行列信息【【cell_col, cell_row】, ...】,为后续的表格写入做准备
    cells_adress = []
    cell_col = []
    cell_row = []
    # 同时获取表格的结构信息
    for index in range(len(Rows)):
    # 获取每一行中的单元格并计算
        cells = Rows[index].getElementsByTagName('Cell')
#     print()
#     print(index+1,'行：')
    
    
    # i : cell索引
        i = 0
        cell_col = []
        cell_row = []
        for index_cell,cell in enumerate(cells) :
        # print('每行的单元格的次序：',index_cell+1)
        # print()
        # 计算得到单元格的起始单元格位置
        # 计算列宽
        #  ss:Index 一般是合并单元格从第一个开始就会出现ss:Index或者是某个纵向合并单元格之后多行的合并单元格
        # ，其后面的数字是在原本一个的基础上又合并的单元格数量
        
        #这是该行的第一个单元格不是从最边上开始的且不是合并单元格
            if(cell.getAttribute("ss:Index") and cell.getAttribute('ss:MergeAcross')==''):
                # print("ss:Index:")
                cell_col = []
                cell_row = []
                i = int(cell.getAttribute("ss:Index")) - 1
                cell_col.append(i)
                width = col_list[i]
                width_start = sum(col_list[:i])
                width_end = width+width_start
            
                cell_width = [width_start, width_end]
            # print('width:',cell_width)
                i = i + 1
                cell_col.append(i)
            
        # 合并单元格的数量和方向
        # MergeAcross横向合并，其后面的数字是在原来一个的基础上合并了单元格的数量
        # #这是该行的第一个单元格不是从最边上开始的而且是合并单元格
            elif(cell.getAttribute("ss:Index") and cell.getAttribute('ss:MergeAcross')):
            # print("ss:Index:ss::Merge")
                cell_col = []
                cell_row = []
                i = i + int(cell.getAttribute("ss:Index")) - 1
                merge_col = int(cell.getAttribute("ss:MergeAcross"))
                cell_col.append(i)
                width = sum(col_list[i:i+merge_col+1])
                width_start = sum(col_list[:i])
                width_end = width+width_start
                cell_width = [width_start, width_end]
            # print('width:',cell_width)
            
                cell_col.append(i)
                i = i+merge_col+1
                cell_col.append(i)
        # 按照正常顺序合并的单元格        
            elif(cell.getAttribute("ss:MergeAcross") ):
                # print("ss:MergeAcross:")
                cell_col = []
                cell_row = []
                merge_col = int(cell.getAttribute("ss:MergeAcross"))
            # 存放每个单元格起始和结束的位置
                width = sum(col_list[i:i+merge_col+1])
                width_start = sum(col_list[:i])
                width_end = width+width_start
                cell_width = [width_start, width_end]
            
            # print('width:',cell_width)
            
                cell_col.append(i)
                i = i+merge_col+1
                cell_col.append(i)
        
        
        
        # 正常的单元格
            elif(cell.getAttribute("ss:Index")=='' and cell.getAttribute("ss:MergeAcross")==''):
                # print("ss:IN ss:m ==   ")
                cell_col = []
                cell_row = []
            
                # print(i)
            
                width = col_list[i]
                cell_col.append(i)
                width_start = sum(col_list[:i])
                width_end = width+width_start
                cell_width = [width_start, width_end]
            
            # print('width:',cell_width)
            
                i = i + 1
                cell_col.append(i)

        # 计算单元格的行高
            if(cell.getAttribute("ss:MergeDown")):
                merge_row = int(cell.getAttribute("ss:MergeDown"))
                height = sum(height_list[index:index+merge_row+1])
                height_start = sum(height_list[:index])
                height_end = height_start+height
                cell_height = [height_start, height_end]
            
            # print('height:',cell_height)
            
                cell_row.append(index)
                cell_row.append(index+merge_row+1)
            
            elif(cell.getAttribute("ss:MergeDown") == ''):
                height_start = sum(height_list[:index])
                height = height_list[index]
                height_end = height_start+height
                cell_height = [height_start, height_end]
            
           #  print('height:',cell_height)
            
                cell_row.append(index)
                cell_row.append(index+1)
        
        # 存放单元格左上和右下角点的坐标
            cell_points = [[height_start,width_start], [height_end, width_end]]
            All_cell_points.append(cell_points)
        # 存放每个单元格的行列位置信息
            cells_adress.append([cell_col, cell_row])
            
    return  All_cell_points, cells_adress, cell_col, cell_row, sum(col_list), sum(height_list)



def path_origin_cell(origin_cell_path, img_jiaozheng):
    
    # 检查是否有存放单元格的文件夹
    if not os.path.exists(origin_cell_path):
        os.makedirs(origin_cell_path)
    # 批量剪裁单元格
    img_cells = []
    i = 0
    img_write =  cv2.imwrite
    for cell_points in All_cell_points:
    
        x_start = int(cell_points[0][0] / height_table * real_row) + x_origin
        x_end = int(cell_points[1][0]/ height_table * real_row) + x_origin
    
        y_start = int(cell_points[0][1] / col_table * real_col ) + y_origin
        y_end = int(cell_points[1][1] / col_table * real_col)+ y_origin
   
     #用来调节框的大小，去除框线对识别的干扰     
        x1 = (x_end - x_start) *0
        y1 = (y_end - y_start) *0
        x_start = int(x_start + x1 )
        x_end = int (x_end - x1 )
        y_start = int (y_start + y1-5)
        y_end = int (y_end - y1)
        cell = img_jiaozheng[x_start:x_end, y_start:y_end]

        img_write (origin_cell_path + str(i) + ".jpg",cell)
        i = i + 1
        img_cells.append(cell)
        
    return img_cells


# In[79]:


def process_origin_cell(orgin_cell_path, binary_cell_path):
    if not os.path.exists(binary_cell_path):
        os.makedirs(binary_cell_path)
    # 单元格图像二值化
    danyuange_names = os.listdir(origin_cell_path)
    img_write = cv2.imwrite
    for imgname in danyuange_names:
        danyuange = cv2.imread(origin_cell_path + imgname)
        img_gray = cv2.cvtColor(danyuange, cv2.COLOR_BGR2GRAY)
        # 用高斯滤波代替均值滤波，更好的保留图像的整体细节
        img_guss = cv2.GaussianBlur(img_gray,(5,5),0)
        # img_gray = cv2.blur(img_gray, (5, 5))
        
        # 图像锐化
        kernel = np.array([[0, -1, 0], [-1, 5, -1], [0, -1, 0]], np.float32) #锐化
        img_sharp = cv2.filter2D(img_gray, -1, kernel=kernel)
        
        # 这里的二值化阈值需要实现自适应
        ret, binary_img = cv2.threshold(img_sharp, 100, 255, cv2.THRESH_OTSU)
        binary_img = ~binary_img
        img_dilate = cv2.dilate(binary_img, (5, 5),iterations = 1)
        # img_dilate = cv2.morphologyEx(binary_img, cv2.MORPH_OPEN, (9, 9),iterations=1)
        img_write(binary_cell_path + imgname, ~img_dilate)


# In[81]:


xml_read_path = "H:\\20201111_dqform\\test\\0001\\0001.xml"
# 原始图像单元格存放地址
origin_cell_path = "H:\\20201111_dqform\\test\\0001\\origin_cell\\"
binary_cell_path = "H:\\20201111_dqform\\test\\0001\\binary_cell\\"



img_jiaozheng =  cv2.imread(jiaozheng_img_path)
# 获取校正之后的图像的四个角的顶点
contuors_jiaozheng_points = contour_points(img_jiaozheng)
# 解析表格xml文件获得表格的结构信息
All_cell_points, cells_adress, cell_col,cell_row, col_table, height_table = xml_read(xml_read_path)




x_origin, y_origin = contuors_jiaozheng_points[0]
# 计算得到表格的总宽、总高的像素值，结合原点对电子表格解析得到的宽高信息转化为像素值
real_col = ((contuors_jiaozheng_points[3][1] - contuors_jiaozheng_points[2][1]) + (contuors_jiaozheng_points[1][1] - contuors_jiaozheng_points[0][1])) / 2
real_row = ((contuors_jiaozheng_points[3][0] - contuors_jiaozheng_points[1][0])+(contuors_jiaozheng_points[2][0] - contuors_jiaozheng_points[0][0])) / 2


# In[85]:


img_cells = path_origin_cell(origin_cell_path, img_jiaozheng)
process_origin_cell(origin_cell_path, binary_cell_path)


# In[17]:


# 单元格边框处理

# cv2.HoughLines()
# 	dst:   输入图像. 它应该是个灰度图 (但事实上是个二值化图)
# 	lines: 储存着检测到的直线的参数对 (r,\theta) 的容器 
# 	rho : 参数极径 r 以像素值为单位的分辨率. 我们使用 1 像素.
# 	theta: 参数极角 \theta 以弧度为单位的分辨率. 我们使用 1度 (即CV_PI/180)
# 	threshold:    设置阈值： 一条直线所需最少的的曲线交点
# 	srn and stn:  参数默认为0

# cv2.HoughLinesP(dst, lines, 1, CV_PI/180, 50, 50, 10 )
# 	dst:    输入图像. 它应该是个灰度图 (但事实上是个二值化图) 
# 	lines:  储存着检测到的直线的参数对 (x_{start}, y_{start}, x_{end}, y_{end}) 的容器
# 	rho :   参数极径 r 以像素值为单位的分辨率. 我们使用 1 像素.
# 	theta:  参数极角 \theta 以弧度为单位的分辨率. 我们使用 1度 (即CV_PI/180)
# 	threshold:    设置阈值： 一条直线所需最少的的曲线交点。超过设定阈值才被检测出线段，值越大，基本上意味着检出的线段越长，检出的线段个数越少。
# 	minLinLength: 能组成一条直线的最少点的数量. 点数量不足的直线将被抛弃.
# 	maxLineGap:   能被认为在一条直线上的两点的最大距离。

# img_cell = cv2.imread("H:\\20201111_dqform\\12_test\\binary_cell\\1.jpg")
# img_cell = cv2.cvtColor(~img_cell, cv2.COLOR_BGR2GRAY)
# edges = cv2.Canny(img_cell,50,150)


# In[22]:


def process_lines(img):
    img_cell = cv2.cvtColor(~img, cv2.COLOR_BGR2GRAY)
    h, w = img_cell.shape
    minLineLength = 0
    maxLineGap = 0
    lines = cv2.HoughLinesP(img_cell, 1, np.pi/180, 1, minLineLength, maxLineGap)
    for line in lines:
        x1 = line[0][0]
        y1 = line[0][1]
        x2 = line[0][2]
        y2 = line[0][3]
        # print(sqrt((x2 - x1)**2 + (y2 - y1)**2))
        if(sqrt((x2 - x1)**2 + (y2 - y1)**2) < 0):
            break
        x_mid = (x1 + x2) / 2
        y_mid = (y1 + y2) / 2
        # 对单元格边缘框线进行筛选
        if(x_mid < 0.01*w or x_mid >0.9*w or y_mid < 0.1*h or y_mid > 0.9*h):
            cv2.line(img_cell,(x1, y1), (x2, y2),(0, 0, 0) , 2)
            
    return img_cell

# 单元格去框线

img_noline_path = "H:\\20201111_dqform\\test\\0004\\img_nolines\\"
img_cells_list = os.listdir(binary_cell_path)

if not os.path.exists(img_noline_path):
        os.makedirs(img_noline_path)
for img_name in img_cells_list:
    img = cv2.imread(binary_cell_path + img_name)
    img_processed = process_lines(img)
    cv2.imwrite(img_noline_path + img_name, ~img_processed)

# img_cell = cv2.cvtColor(~img_cell, cv2.COLOR_BGR2GRAY)


# In[ ]:


binary_cell_path = "C:\\Users\\lg\\Desktop\\form_ocr_excel\\hand write\\numbers_shouxie\\hand_12\\binary_cell\\"
# 原始表格的读取路径
worksheet_read_path = "C:\\Users\\lg\\Desktop\\form_ocr_excel\\hand write\\numbers_shouxie\\hand_12\\1.xlsx"
# 识别结果电子表格的存放路径
worksheet_write_path = "C:\\Users\\lg\\Desktop\\form_ocr_excel\\hand write\\numbers_shouxie\\hand_12\\20201109.xlsx"


# 新训练
def write_worksheet(worksheet_read_path,worksheet_write_path):
    workbook=openpyxl.load_workbook(worksheet_read_path)
    worksheet=workbook.worksheets[0]
    col_dict = {0:'A',1:'B',2:'C',3:'D',4:'E',5:'F',6:'G',7:'H',8:'I',9:'J',10:'K',11:'L', }
#     hand_list = [5,26,27,28,29,30,31,32,33,34,36,37,38,39,40,41,42,43,44,56,57,58,59,60,61,62,63,64,
#                  66,67,68,69,70,71,72,73,74,77,78,79,80,81,82,83,84,85,87,88,89,90,91,92,93,94,95,102,103]
    hand_list = [43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,
                69,70,71,72,73,74,75,77,79,80,81,82,83,84,85]
    hand_list = [242, 243,244,245,24,247,249,250,251,252,253,254,255,256,257,258,259,260,262,263,264,265,266,267,268,269,270,271,272,273,
                274,275,276,277,278,279,281,282,283,284,285,286,287,288,289,290,291,292,294,295,296,297,298,299,300]
    img_read = cv2.imread
    image_to_string = pytesseract.image_to_string
    for i, cell in enumerate(cells_adress):
        col_start = cell[0][0]
        # col_end = cell[0][1]
        row_start = cell[1][0]
        # row_end = cell[1][1]
        # print(row_start,row_end)
        index = col_dict[col_start] + str(row_start+1)
        
        if(i in hand_list):
        
            # print("原始数据：", worksheet[index].value)
            img = img_read(binary_cell_path + str(i) + ".jpg")
            text = image_to_string(img,lang='zimu4',config=tessdata_dir_config)
            text = text.replace(' ', '')
            print(text)
            
            # print(i)
            worksheet[index].value = text[0:-2]
            
        else:
            continue
            img = img_read(binary_cell_path + str(i) + ".jpg")
            text = image_to_string(img,lang='font3',config=tessdata_dir_config)
            
            text = text.replace(' ', '')
            
            worksheet[index].value = text[0:-2]
            print(text)
            
    if (workbook.save(filename=worksheet_write_path)):
        print("识别信息写入表格成功！")
        
    else :
        print("识别信息写入表格失败！")


# 读取纸质版表格的原始图像
img = cv2.imread(origin_img_path)
# 获取表格框线的四个角的顶点
contours_points = contour_points(img)
# 对原始图像进行校正并保存
img_crroect(jiaozheng_img_path, contours_points, img)
# 读取校正后的图像，作为后续处理的图像
img_jiaozheng =  cv2.imread(jiaozheng_img_path)
# 获取校正之后的图像的四个角的顶点
contuors_jiaozheng_points = contour_points(img_jiaozheng)
# 解析表格xml文件获得表格的结构信息
All_cell_points, cells_adress, cell_col,cell_row, col_table, height_table = xml_read(xml_read_path)

# 将左上角的顶点作为表格的原点
x_origin, y_origin = contuors_jiaozheng_points[0]
# 计算得到表格的总宽、总高的像素值，结合原点对电子表格解析得到的宽高信息转化为像素值
real_col = ((contuors_jiaozheng_points[3][1] - contuors_jiaozheng_points[2][1]) + (contuors_jiaozheng_points[1][1] - contuors_jiaozheng_points[0][1])) / 2
real_row = ((contuors_jiaozheng_points[3][0] - contuors_jiaozheng_points[1][0])+(contuors_jiaozheng_points[2][0] - contuors_jiaozheng_points[0][0])) / 2
# # 对表格独立单元格进行剪裁，并保存
# img_cells = path_origin_cell(origin_cell_path, img_jiaozheng)
# # 对剪裁出的单元格图像进行预处理，以便后续的图像识别
# process_origin_cell(origin_cell_path, binary_cell_path)
# # 对单元格图像进行文字识别，并对应写入电子表格并进行保存
# write_worksheet(worksheet_read_path,worksheet_write_path)


# In[32]:


# # 对表格独立单元格进行剪裁，并保存
# # 对剪裁出的单元格图像进行预处理，以便后续的图像识别
img_cells = path_origin_cell(origin_cell_path, img_jiaozheng)
process_origin_cell(origin_cell_path, binary_cell_path)


# In[32]:


# 对单元格图像进行文字识别，并对应写入电子表格并进行保存
write_worksheet(worksheet_read_path,worksheet_write_path)




# 原始图像存放路径
origin_img_path =  "C:\\Users\\lg\\Desktop\\form_ocr_excel\\hand write\\numbers_shouxie\\hand_12\\hand_12.jpg"
img = cv2.imread(origin_img_path)
# 原始图像校正后的存放路径
jiaozheng_img_path = "C:\\Users\\lg\\Desktop\\form_ocr_excel\\hand write\\numbers_shouxie\\hand_12\\hand12_jiaozheng.jpg"
# 纸质版表格文件的电子版路径
xml_read_path = "C:\\Users\\lg\\Desktop\\form_ocr_excel\\hand write\\numbers_shouxie\\hand_12\\hand_12.xml"
# 原始图像单元格存放地址
origin_cell_path = "C:\\Users\\lg\\Desktop\\form_ocr_excel\\hand write\\numbers_shouxie\\hand_12\\origin_cell\\"
# 单元格预处理后的图像的存放位置
binary_cell_path = "C:\\Users\\lg\\Desktop\\form_ocr_excel\\hand write\\numbers_shouxie\\hand_12\\binary_cell\\"
# 原始表格的读取路径
worksheet_read_path = "C:\\Users\\lg\\Desktop\\form_ocr_excel\\hand write\\numbers_shouxie\\hand_12\\1.xlsx"
# 识别结果电子表格的存放路径
worksheet_write_path = "C:\\Users\\lg\\Desktop\\form_ocr_excel\\hand write\\numbers_shouxie\\hand_12\\20201109.xlsx"


# In[42]:


def process():
    # 读取纸质版表格的原始图像
    img = cv2.imread(origin_img_path)
    # 获取表格框线的四个角的顶点
    contours_points = contour_points(img)
    # 对原始图像进行校正并保存
    img_crroect(jiaozheng_img_path, contours_points, img)
    # 读取校正后的图像，作为后续处理的图像
    img_jiaozheng =  cv2.imread(jiaozheng_img_path)
    # 获取校正之后的图像的四个角的顶点
    contuors_jiaozheng_points = contour_points(img_jiaozheng)
    # 解析表格xml文件获得表格的结构信息
    All_cell_points, cells_adress, cell_col,cell_row, col_table, height_table = xml_read(xml_read_path)

    # 将左上角的顶点作为表格的原点
    x_origin, y_origin = contuors_jiaozheng_points[0]
    # 计算得到表格的总宽、总高的像素值，结合原点对电子表格解析得到的宽高信息转化为像素值
    real_col = ((contuors_jiaozheng_points[3][1] - contuors_jiaozheng_points[2][1]) + (contuors_jiaozheng_points[1][1] - contuors_jiaozheng_points[0][1])) / 2
    real_row = ((contuors_jiaozheng_points[3][0] - contuors_jiaozheng_points[1][0])+(contuors_jiaozheng_points[2][0] - contuors_jiaozheng_points[0][0])) / 2
    # 对表格独立单元格进行剪裁，并保存
    img_cells = path_origin_cell(origin_cell_path, img_jiaozheng)
    process_origin_cell(origin_cell_path, binary_cell_path)
    # 对单元格图像进行文字识别，并对应写入电子表格并进行保存
    write_worksheet(worksheet_read_path,worksheet_write_path)


# In[ ]:





# In[ ]:





# In[48]:


# 2020.11.11算法调试以及优化


# In[73]:


# 原始图像存放路径
origin_img_path =  "H:\\20201111_dqform\\1.png"
# 原始图像校正后的存放路径
jiaozheng_img_path = "H:\\20201111_dqform\\1_jiaozheng.png"

img = cv2.imread(origin_img_path)

# plt.imshow(img)


# In[74]:


# 获取表格框线的四个角的顶点
contours_points = contour_points(img)
# 对原始图像进行校正并保存
img_crroect(jiaozheng_img_path, contours_points, img)
img_jiaozheng =  cv2.imread(jiaozheng_img_path)


# In[ ]:




